/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.ibatis.extension.toolkit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日期操作工具类
 *
 * @author wangmm@ketr.com.cn
 * @date 2020/8/3
 */
public class DateUtils {

    private static final Log LOGGER = LogFactory.getLog(DateUtils.class);

    public static Date parse(Object value) {

        //使用多种日期转换
        for (DatePattern datePattern : DatePattern.values()) {
            try {
                Date parse = datePattern.simpleDateFormat().parse(String.valueOf(value));
                LOGGER.debug("Date format [" + value + "] -> [" + datePattern.getFormat() + "]");
                return parse;
            } catch (ParseException ignored) {
            }
        }

        //全部转换失败 返回空
        return null;
    }

    /**
     * 日期格式枚举(注意将最长的放到前面)
     */
    enum DatePattern {

        //-------------------------------------------------------------------------------------------------------------------------------- Normal

        /**
         * 标准日期时间格式，精确到毫秒：yyyy-MM-dd HH:mm:ss.SSS
         */
        NORM_DATETIME_MS_PATTERN("yyyy-MM-dd HH:mm:ss.SSS"),

        /**
         * 标准日期时间格式，精确到秒：yyyy-MM-dd HH:mm:ss
         */
        NORM_DATETIME_PATTERN("yyyy-MM-dd HH:mm:ss"),

        /**
         * 标准日期时间格式，精确到分：yyyy-MM-dd HH:mm
         */
        NORM_DATETIME_MINUTE_PATTERN("yyyy-MM-dd HH:mm"),

        /**
         * 标准日期格式：yyyy-MM-dd
         */
        NORM_DATE_PATTERN("yyyy-MM-dd"),

        /**
         * 标准时间格式：HH:mm:ss
         */
        NORM_TIME_PATTERN("HH:mm:ss"),

        /**
         * 标准日期格式：yyyy年MM月dd日
         */
        CHINESE_DATE_PATTERN("yyyy年MM月dd日"),

        //-------------------------------------------------------------------------------------------------------------------------------- Pure

        /**
         * 标准日期格式：yyyyMMddHHmmssSSS
         */
        PURE_DATETIME_MS_PATTERN("yyyyMMddHHmmssSSS"),

        /**
         * 标准日期格式：yyyyMMddHHmmss
         */
        PURE_DATETIME_PATTERN("yyyyMMddHHmmss"),

        /**
         * 标准日期格式：yyyyMMdd
         */
        PURE_DATE_PATTERN("yyyyMMdd"),

        /**
         * 标准日期格式：HHmmss
         */
        PURE_TIME_PATTERN("HHmmss"),

        //-------------------------------------------------------------------------------------------------------------------------------- Others
        /**
         * HTTP头中日期时间格式：EEE, dd MMM yyyy HH:mm:ss z
         */
        HTTP_DATETIME_PATTERN("EEE, dd MMM yyyy HH:mm:ss z"),

        /**
         * JDK中日期时间格式：EEE MMM dd HH:mm:ss zzz yyyy
         */
        JDK_DATETIME_PATTERN("EEE MMM dd HH:mm:ss zzz yyyy"),

        /**
         * UTC时间：yyyy-MM-dd'T'HH:mm:ss'Z'
         */
        UTC_PATTERN("yyyy-MM-dd'T'HH:mm:ss'Z'"),

        /**
         * UTC时间：yyyy-MM-dd'T'HH:mm:ssZ
         */
        UTC_WITH_ZONE_OFFSET_PATTERN("yyyy-MM-dd'T'HH:mm:ssZ"),

        /**
         * UTC时间：yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
         */
        UTC_MS_PATTERN("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"),

        /**
         * UTC时间：yyyy-MM-dd'T'HH:mm:ssZ
         */
        UTC_MS_WITH_ZONE_OFFSET_PATTERN("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

        /**
         * 格式化
         */
        private final String format;

        /**
         * 使用 ThreadLocal 解决 SimpleDateFormat 的线程安全问题
         */
        private final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<>();

        DatePattern(String format) {
            this.format = format;
        }

        public String getFormat() {
            return format;
        }

        /**
         * 获取格式化对象
         *
         * @return SimpleDateFormat
         */
        public SimpleDateFormat simpleDateFormat() {
            SimpleDateFormat simpleDateFormat = sdf.get();
            if (simpleDateFormat == null) {
                simpleDateFormat = new SimpleDateFormat(format);
                sdf.set(simpleDateFormat);
            }
            return simpleDateFormat;
        }

        @Override
        public String toString() {
            return "DatePattern{" +
                    "format='" + format + '\'' +
                    '}';
        }
    }
}
